package org.rsbot.gui;

import java.awt.event.ActionListener;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;

import org.rsbot.bot.Bot;
import org.rsbot.event.impl.DrawInventory;
import org.rsbot.event.impl.DrawItems;
import org.rsbot.event.impl.DrawModel;
import org.rsbot.event.impl.DrawMouse;
import org.rsbot.event.impl.DrawNPCs;
import org.rsbot.event.impl.DrawObjects;
import org.rsbot.event.impl.DrawPlayers;
import org.rsbot.event.impl.MessageLogger;
import org.rsbot.event.impl.TAnimation;
import org.rsbot.event.impl.TCamera;
import org.rsbot.event.impl.TFPS;
import org.rsbot.event.impl.TFloorHeight;
import org.rsbot.event.impl.TLoginIndex;
import org.rsbot.event.impl.TMenu;
import org.rsbot.event.impl.TMenuActions;
import org.rsbot.event.impl.TMousePosition;
import org.rsbot.event.impl.TOrientation;
import org.rsbot.event.impl.TPlayerPosition;
import org.rsbot.event.impl.TTab;
import org.rsbot.event.impl.TUserInputAllowed;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.event.listeners.TextPaintListener;
import org.rsbot.util.GlobalConfiguration;

public class BotMenuBar extends JMenuBar {

    private static final long serialVersionUID = 971579975301998332L;
    public static final Map<String, Class<?>> DEBUG_MAP = new LinkedHashMap<String, Class<?>>();
    public static final String[] TITLES;
    public static final String[][] ELEMENTS;
    public static final ImageIcon bug = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.BUG, GlobalConfiguration.Paths.BUG));
    public static final ImageIcon account = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.ACCOUNT, GlobalConfiguration.Paths.ACCOUNT));
    public static final ImageIcon start = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.ICON_PLAY, GlobalConfiguration.Paths.ICON_PLAY));
    public static final ImageIcon stop = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.STOP_DO, GlobalConfiguration.Paths.STOP_DO));
    public static final ImageIcon pauseico = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.ICON_PAUSE, GlobalConfiguration.Paths.ICON_PAUSE));
    public static final ImageIcon input = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.ICON_TICK, GlobalConfiguration.Paths.ICON_TICK));
    public static final ImageIcon noinput = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.ICON_DELETE, GlobalConfiguration.Paths.ICON_DELETE));
    public static final ImageIcon cpu = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.CPU, GlobalConfiguration.Paths.CPU));
    public static final ImageIcon exit = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.GUI_CLOSE, GlobalConfiguration.Paths.GUI_CLOSE));
    public static final ImageIcon sshot = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.SHOT_DO, GlobalConfiguration.Paths.SHOT_DO));
    public static final ImageIcon bugpen = new ImageIcon(GlobalConfiguration.getImage(GlobalConfiguration.Paths.Resources.PENCIL, GlobalConfiguration.Paths.PENCIL));

    static {
        System.out.println(GlobalConfiguration.RUNNING_FROM_JAR);
        // Text
        DEBUG_MAP.put("Game State", TLoginIndex.class);
        DEBUG_MAP.put("Current Tab", TTab.class);
        DEBUG_MAP.put("Camera", TCamera.class);
        DEBUG_MAP.put("Animation", TAnimation.class);
        DEBUG_MAP.put("Floor Height", TFloorHeight.class);
        DEBUG_MAP.put("Player Position", TPlayerPosition.class);
        DEBUG_MAP.put("Orientation", TOrientation.class);
        DEBUG_MAP.put("Mouse Position", TMousePosition.class);
        DEBUG_MAP.put("User Input Allowed", TUserInputAllowed.class);
        DEBUG_MAP.put("Menu Actions", TMenuActions.class);
        DEBUG_MAP.put("Menu", TMenu.class);
        DEBUG_MAP.put("FPS", TFPS.class);

        // Paint
        DEBUG_MAP.put("Players", DrawPlayers.class);
        DEBUG_MAP.put("NPCs", DrawNPCs.class);
        DEBUG_MAP.put("Objects", DrawObjects.class);
        DEBUG_MAP.put("Models", DrawModel.class);
        DEBUG_MAP.put("Mouse", DrawMouse.class);
        DEBUG_MAP.put("Inventory", DrawInventory.class);
        DEBUG_MAP.put("Ground Items", DrawItems.class);
        //DEBUG_MAP.put("Calc Test", DrawBoundaries.class);
        //DEBUG_MAP.put("Settings", DrawSettings.class);

        // Other
        DEBUG_MAP.put("Log Messages", MessageLogger.class);

        TITLES = new String[]{"Client", "Screen Shots", "Anti-Bans", "Randoms",
                    "Hide", "Debug", "Skins", "Help"};
        ELEMENTS = new String[][]{
                    /*{"New Bot", "Close Bot", "-", "Run Script", "Stop Script", 
                    "Pause Script", "-", "Save Screenshot", "-", "Exit"},*/
                    {"Accounts", "-", "Run Script", "Stop Script", "Pause Script",
                        "-", "ToggleF Force Input", "ToggleF Less CPU", "-", "Exit"},
                    {"Save ScreenShot", "Save ScreenShot (UnCen)"},
                    {"ToggleF Disable All Anti-Bans", "ToggleF Disable Auto Login",
                        "ToggleF Disable Break Handler"},
                    constrconuctRandoms(),
                    constructHides(),
                    constructDebugs(),
                    constructThemes(),
                    constrconuctHelp()};
    }

    private static String[] constrconuctRandoms() {
        List<String> randomItems = new ArrayList<String>();
        randomItems.add("Disable All Random Solving");
        randomItems.add("Disable Bee Hive");
        randomItems.add("Disable Capn Arnav");
        randomItems.add("Disable Certer");
        randomItems.add("Disable Drill Demon");
        randomItems.add("Disable Exam");
        randomItems.add("Disable First Time Death");
        randomItems.add("Disable Freaky Forester");
        randomItems.add("Disable Frog Cave");
        randomItems.add("Disable Grave Digger");
        randomItems.add("Disable Leave Safe Area");
        randomItems.add("Disable Lost And Found");
        randomItems.add("Disable Maze");
        randomItems.add("Disable Mime");
        randomItems.add("Disable Molly");
        randomItems.add("Disable Pillory");
        randomItems.add("Disable Pinball");
        randomItems.add("Disable Prison");
        randomItems.add("Disable Quiz Solver");
        randomItems.add("Disable Sandwhich Lady");
        randomItems.add("Disable Scape Rune Island");

        for (ListIterator<String> it = randomItems.listIterator(); it.hasNext();) {
            String s = it.next();
            if (!s.equals("-")) {
                it.set("ToggleF " + s);
            }
        }
        return randomItems.toArray(new String[randomItems.size()]);
    }

    private static String[] constructHides() {
        List<String> hideItems = new ArrayList<String>();
        hideItems.add("Hide Toolbar");
        hideItems.add("Hide Option Buttons");
        hideItems.add("Hide Option Console");
        //hideItems.add("Hide Tray Icon");
        for (ListIterator<String> it = hideItems.listIterator(); it.hasNext();) {
            String s = it.next();
            if (!s.equals("-")) {
                it.set("ToggleF " + s);
            }
        }
        return hideItems.toArray(new String[hideItems.size()]);
    }

    private static String[] constructDebugs() {
        List<String> debugItems = new ArrayList<String>();
        debugItems.add("All Debugging");
        debugItems.add("-");
        for (String key : DEBUG_MAP.keySet()) {
            Class<?> el = DEBUG_MAP.get(key);
            if (PaintListener.class.isAssignableFrom(el)) {
                debugItems.add(key);
            }
        }
        debugItems.add("-");
        for (String key : DEBUG_MAP.keySet()) {
            final Class<?> el = DEBUG_MAP.get(key);
            if (TextPaintListener.class.isAssignableFrom(el)) {
                debugItems.add(key);
            }
        }
        debugItems.add("-");
        for (String key : DEBUG_MAP.keySet()) {
            Class<?> el = DEBUG_MAP.get(key);
            if (!(TextPaintListener.class.isAssignableFrom(el)) && !(PaintListener.class.isAssignableFrom(el))) {
                debugItems.add(key);
            }
        }
        for (ListIterator<String> it = debugItems.listIterator(); it.hasNext();) {
            String s = it.next();
            if (!s.equals("-")) {
                it.set("ToggleF " + s);
            }
        }
        return debugItems.toArray(new String[debugItems.size()]);
    }

    private static String[] constructThemes() {
        final String[] themeSet = new String[BotGUI.themes.size()];
        int themeIndex = 0;
        for (String key : BotGUI.themes.keySet()) {
            themeSet[themeIndex] = "Toggle" + (key.equals("System") ? "F" : "F") + " " + key;
            themeIndex++;
        }
        return themeSet;
    }

    private static String[] constrconuctHelp() {
        List<String> helpItems = new ArrayList<String>();
        helpItems.add("Troubleshootin");
        helpItems.add("Site");
        helpItems.add("Forums");
        helpItems.add("Wiki");
        helpItems.add("Facebook");
        helpItems.add("Project");
        helpItems.add("The Client");
        helpItems.add("The Makers");

        for (ListIterator<String> it = helpItems.listIterator(); it.hasNext();) {
            String s = it.next();
            if (!s.equals("-")) {
                it.set("ToggleF " + s);
            }
        }
        return helpItems.toArray(new String[helpItems.size()]);
    }
    public static Map<String, JCheckBoxMenuItem> eventCheckMap = new HashMap<String, JCheckBoxMenuItem>();
    public static Map<String, JCheckBoxMenuItem> commandCheckMap = new HashMap<String, JCheckBoxMenuItem>();
    public static Map<String, JMenuItem> commandMenuItem = new HashMap<String, JMenuItem>();
    private ActionListener listener;

    public BotMenuBar(ActionListener listener) {
        this.listener = listener;
        for (int i = 0; i < TITLES.length; i++) {
            String title = TITLES[i];
            String[] elems = ELEMENTS[i];
            add(constructMenu(title, elems));
        }
    }

    public void setOverrideInput(boolean force) {
        commandCheckMap.get("Force Input").setSelected(force);
        commandCheckMap.get("Force Input").setIcon(input);
    }

    public void setPauseScript(boolean pause) {
        commandMenuItem.get("Pause Script").setText(pause ? "Resume Script" : "Pause Script");
        commandMenuItem.get("Pause Script").setIcon(pause ? start : pauseico);
    }

    public void setBot(Bot bot) {
        commandMenuItem.get("Accounts").setIcon(account);
        commandMenuItem.get("Run Script").setIcon(start);
        commandMenuItem.get("Stop Script").setIcon(stop);
        commandMenuItem.get("Pause Script").setIcon(pauseico);
        commandCheckMap.get("Force Input").setIcon(noinput);
        commandCheckMap.get("Less CPU").setIcon(cpu);
        commandMenuItem.get("Exit").setIcon(exit);
        commandMenuItem.get("Save ScreenShot").setIcon(sshot);
        commandCheckMap.get("All Debugging").setIcon(bugpen);
        eventCheckMap.get("Game State").setIcon(bug);
        eventCheckMap.get("Current Tab").setIcon(bug);
        eventCheckMap.get("Camera").setIcon(bug);
        eventCheckMap.get("Animation").setIcon(bug);
        eventCheckMap.get("Floor Height").setIcon(bug);
        eventCheckMap.get("Player Position").setIcon(bug);
        eventCheckMap.get("Orientation").setIcon(bug);
        eventCheckMap.get("Mouse Position").setIcon(bug);
        eventCheckMap.get("User Input Allowed").setIcon(bug);
        eventCheckMap.get("Menu Actions").setIcon(bug);
        eventCheckMap.get("Menu").setIcon(bug);
        eventCheckMap.get("FPS").setIcon(bug);
        eventCheckMap.get("Players").setIcon(bug);
        eventCheckMap.get("NPCs").setIcon(bug);
        eventCheckMap.get("Objects").setIcon(bug);
        eventCheckMap.get("Models").setIcon(bug);
        eventCheckMap.get("Mouse").setIcon(bug);
        eventCheckMap.get("Inventory").setIcon(bug);
        eventCheckMap.get("Ground Items").setIcon(bug);
        //eventCheckMap.get("Calc Test").setIcon(bug);
        //eventCheckMap.get("Settings").setIcon(bug);
        eventCheckMap.get("Log Messages").setIcon(bug);
        if (bot == null) {
            //commandMenuItem.get("Close Bot").setEnabled(false);
            commandMenuItem.get("Run Script").setEnabled(false);
            commandMenuItem.get("Stop Script").setEnabled(false);
            commandMenuItem.get("Pause Script").setEnabled(false);
            //commandMenuItem.get("Save ScreenShot").setEnabled(false);
            for (JCheckBoxMenuItem item : eventCheckMap.values()) {
                item.setSelected(false);
                item.setEnabled(false);
            }
            disable("All Debugging", "Force Input", "Less CPU",
                    "Disable All Random Solving", "Disable All Anti-Bans",
                    "Disable Auto Login", "Disable Break Handler",
                    "Disable Capn Arnav", "Disable Bee Hive", "Disable Certer",
                    "Disable Drill Demon", "Disable Exam", "Disable First Time Death",
                    "Disable Freaky Forester", "Disable Frog Cave",
                    "Disable Grave Digger", "Disable Leave Safe Area",
                    "Disable Lost And Found", "Disable Maze", "Disable Mime",
                    "Disable Molly", "Disable Pillory", "Disable Pinball",
                    "Disable Prison", "Disable Quiz Solver",
                    "Disable Sandwhich Lady", "Disable Scape Rune Island");
        } else {
            //commandMenuItem.get("Close Bot").setEnabled(true);
            commandMenuItem.get("Run Script").setEnabled(true);
            commandMenuItem.get("Stop Script").setEnabled(true);
            commandMenuItem.get("Pause Script").setEnabled(true);
            commandMenuItem.get("Save ScreenShot").setEnabled(true);
            int selections = 0;
            for (Map.Entry<String, JCheckBoxMenuItem> entry : eventCheckMap.entrySet()) {
                entry.getValue().setEnabled(true);
                boolean selected = bot.hasListener(DEBUG_MAP.get(entry.getKey()));
                entry.getValue().setSelected(selected);
                if (selected) {
                    ++selections;
                }
            }
            enable("All Debugging", selections == eventCheckMap.size());
            enable("Force Input", bot.overrideInput);
            enable("Less CPU", bot.disableRendering);
            /* Antibans */
            enable("Disable All Anti-Bans", bot.disableRandoms);
            enable("Disable Auto Login", bot.disableAutoLogin);
            enable("Disable Break Handler", bot.disableBreakHandler);
            /* Randoms */
            enable("Disable All Random Solving", bot.disableRandoms);
            enable("Disable Bee Hive", bot.disableBeehiveSolver);
            enable("Disable Capn Arnav", bot.disableCapnArnav);
            enable("Disable Capn Arnav", bot.disableCapnArnav);
            enable("Disable Certer", bot.disableCerter);
            enable("Disable Drill Demon", bot.disableDrillDemon);
            enable("Disable Exam", bot.disableExam);
            enable("Disable First Time Death", bot.disableFirstTimeDeath);
            enable("Disable Freaky Forester", bot.disableFreakyForester);
            enable("Disable Frog Cave", bot.disableFrogCave);
            enable("Disable Grave Digger", bot.disableGraveDigger);
            enable("Disable Leave Safe Area", bot.disableLeaveSafeArea);
            enable("Disable Lost And Found", bot.disableLostAndFound);
            enable("Disable Maze", bot.disableMaze);
            enable("Disable Mime", bot.disableMime);
            enable("Disable Molly", bot.disableMolly);
            enable("Disable Pillory", bot.disablePillory);
            enable("Disable Pinball", bot.disablePinball);
            enable("Disable Prison", bot.disablePrison);
            enable("Disable Quiz Solver", bot.disableQuizSolver);
            enable("Disable Sandwhich Lady", bot.disableSandwhichLady);
            enable("Disable Scape Rune Island", bot.disableScapeRuneIsland);
        }
    }

    public JCheckBoxMenuItem getCheckBox(String key) {
        return commandCheckMap.get(key);
    }

    public JCheckBoxMenuItem getCheckBoxEvent(String key) {
        return eventCheckMap.get(key);
    }

    private void disable(String... items) {
        for (String item : items) {
            commandCheckMap.get(item).setSelected(false);
            commandCheckMap.get(item).setEnabled(false);
        }
    }

    private void enable(String item, boolean selected) {
        commandCheckMap.get(item).setSelected(selected);
        commandCheckMap.get(item).setEnabled(true);
    }

    private JMenu constructMenu(String title, String[] elems) {
        JMenu menu = new JMenu(title);
        for (String e : elems) {
            if (e.equals("-")) {
                menu.add(new JSeparator());
            } else {
                JMenuItem jmi;
                if (e.startsWith("Toggle")) {
                    e = e.substring("Toggle".length());
                    char state = e.charAt(0);
                    e = e.substring(2);
                    jmi = new JCheckBoxMenuItem(e);
                    if ((state == 't') || (state == 'T')) {
                        jmi.setSelected(true);
                    }
                    if (DEBUG_MAP.containsKey(e)) {
                        eventCheckMap.put(e, (JCheckBoxMenuItem) jmi);
                    }
                    commandCheckMap.put(e, (JCheckBoxMenuItem) jmi);
                } else {
                    jmi = new JMenuItem(e);
                    commandMenuItem.put(e, jmi);
                }
                jmi.addActionListener(listener);
                jmi.setActionCommand(title + "." + e);
                menu.add(jmi);
            }
        }
        return menu;
    }
}
